package Test;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 题目：JAVA获取二维数组中每一列的最小值
 * <p>
 * 重点：java中是允许二维数组中一维数组长度不一样的！！
 *
 * @author wangchenghao
 * @date 2021/5/10
 **/
public class test {

    //方法一：行列转换
    public static void getListMin(List<List<Integer>> array) {
        int maxLength = 0;
        List<List<Integer>> tempArray = new ArrayList<>();
        //获取最长的一维数组的长度做为列数
        for (List<Integer> integers : array) {
            for (int j = 0; j < integers.size(); j++) {
                maxLength = Math.max(integers.size(), maxLength);
            }
        }
        //外层循环列数
        for (int j = 0; j < maxLength; j++) {
            //存储一列数据
            List<Integer> list = new ArrayList<>();
            //内层循环行数，放入同一列数据
            for (List<Integer> integers : array) {
                //防止越界
                if (integers.size() > j) {
                    list.add(integers.get(j));
                }
            }
            tempArray.add(list);
        }
        System.out.println("列的最小值分别为:");
        //输出每列最小值
        for (int i = 0; i < tempArray.size(); i++) {
            System.out.println("第" + i + "列最小值为:" + Collections.min(tempArray.get(i)));
        }

        ////输出每列最小值,迭代器
        Iterator<List<Integer>> iterator = tempArray.iterator();
        int j = 0;
        while (iterator.hasNext()) {
            //iterator.next()返回迭代的下一个元素
            System.out.println("第" + j++ + "列最小值为:" + Collections.min(iterator.next()));
        }

//        //输出每列最小值,lambda
//        tempArray.forEach(t -> System.out.print(t.stream().min(Integer::compare).get() + " "));

    }

    //方法二：依次获取某个一维数组中的数据，与其他一维数组中对应位置的数据去比较，获取最小值
    //考虑到列数，需要将二维数组中的数据按一维数组长度排序
    public static void getListMin2(List<List<Integer>> array) {

        //二维数组中的数据按一维数组长度排序
        List<List<Integer>> tempArray = new ArrayList<>();
        Map<Integer, Integer> listLengthMap = new HashMap<>();
        int index = 0;
        for (List<Integer> integers : array) {
            listLengthMap.put(index++, integers.size());
        }
        LinkedHashMap<Integer, Integer> map = (LinkedHashMap<Integer, Integer>) sortByValue(listLengthMap);

        for (Map.Entry<Integer, Integer> next : map.entrySet()) {
            tempArray.add(array.get(next.getKey()));
        }
        // 获取列的个数
        int maxLength = array.get(0).size();
        int[] otherArray = new int[maxLength];
        //外层循环列 从0列开始
        for (int i = 0; i < maxLength; i++) {
            int min = array.get(0).get(i);// 寄存该列的第一个数字为最小值(即第一个一维数组中某列的数据)
            for (int j = 1; j < array.size(); j++) {
                //防止索引越界
                if (array.get(j).size() <= i) {
                    break;
                }
                //拿第一个一维数组中某列的数据和其他行相同列的数据比较
                if (array.get(j).get(i) < min) {
                    min = array.get(j).get(i);
                }
            }
            otherArray[i] = min;
        }
        System.out.println("列的最小值分别为:");
        for (int i = 0; i < maxLength; i++) {
            System.out.println("第" + i + "列的最小值分别为: " + otherArray[i]);
        }

    }


    public static void main(String[] args) {
        int[][] array = {{1, 3, 5}, {8, 8}, {7, 6}, {3, 0}, {4, 5}};
        //获取二维数组中每一列的最小值
        getListMin(arrayToList(array));

        getListMin2(arrayToList(array));
    }

    /**
     * 二维数组转集合
     *
     * @param array 数组
     * @return 集合
     */
    public static List<List<Integer>> arrayToList(int[][] array) {
        List<List<Integer>> listTest = new ArrayList<>();
        for (int i = 0; i < array.length; i++) {
            List<Integer> columnList = new ArrayList<>();
            for (int j = 0; j < array[i].length; j++) {
                columnList.add(j, array[i][j]);
            }
            listTest.add(i, columnList);
        }
        return listTest;
    }

    /**
     * 使用 Map按value进行排序
     *
     * @param map
     * @return
     */

    public static Map sortByValue(Map map) {

        List<Map.Entry<Integer, Integer>> list = new ArrayList<Map.Entry<Integer, Integer>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
//                return o1.getValue().compareTo(o2.getValue());//升序
                return o2.getValue().compareTo(o1.getValue()); //降序
            }
        });

        Map newMap = new LinkedHashMap();
        Iterator<Map.Entry<Integer, Integer>> iter = list.iterator();
        Map.Entry tmpEntry = null;
        while (iter.hasNext()) {
            tmpEntry = iter.next();
            newMap.put(tmpEntry.getKey(), tmpEntry.getValue());
        }

        return newMap;
    }


}
